package org.jim.server.helper.redis;

import org.apache.commons.lang3.StringUtils;
import org.jim.common.ImConfig;
import org.jim.common.ImSessionContext;
import org.jim.common.cache.redis.RedisCache;
import org.jim.common.cache.redis.RedisCacheManager;
import org.jim.common.listener.AbstractImBindListener;
import org.jim.common.packets.Client;
import org.jim.common.packets.Group;
import org.jim.common.packets.User;
import org.jim.common.utils.ImKit;
import org.tio.core.ChannelContext;

import java.io.Serializable;
import java.util.List;

/**
 * 消息持久化绑定监听器
 *
 * @author WChao
 * @date 2018年4月8日 下午4:12:31
 */
public class RedisImBindListener extends AbstractImBindListener {

    private RedisCache groupCache = null;
    private RedisCache userCache = null;
    private final String SUBFIX = ":";

    public RedisImBindListener() {
        this(null);
    }

    public RedisImBindListener(ImConfig imConfig) {
        this.imConfig = imConfig;
        groupCache = RedisCacheManager.getCache(GROUP);
        userCache = RedisCacheManager.getCache(USER);
    }

    static {
        RedisCacheManager.register(USER, Integer.MAX_VALUE, Integer.MAX_VALUE);
        RedisCacheManager.register(GROUP, Integer.MAX_VALUE, Integer.MAX_VALUE);
        RedisCacheManager.register(STORE, Integer.MAX_VALUE, Integer.MAX_VALUE);
        RedisCacheManager.register(PUSH, Integer.MAX_VALUE, Integer.MAX_VALUE);

    }

    @Override
    public void onAfterGroupBind(ChannelContext channelContext, String group) throws Exception {
        if (!isStore()) {
            return;
        }
        initGroupUsers(group, channelContext);
    }

    @Override
    public void onAfterGroupUnbind(ChannelContext channelContext, String group) throws Exception {
        if (!isStore()) {
            return;
        }
        String userid = channelContext.getUserid();
        //移除群组成员;
        groupCache.listRemove(group + SUBFIX + USER, userid);
        //移除成员群组;
        userCache.listRemove(userid + SUBFIX + GROUP, group);
        RedisCacheManager.getCache(PUSH).remove(GROUP + SUBFIX + group + SUBFIX + userid);
    }

    @Override
    public void onAfterUserBind(ChannelContext channelContext, String userid) throws Exception {
        if (!isStore()) {
            return;
        }
        ImSessionContext imSessionContext = (ImSessionContext) channelContext.getAttribute();
        Client client = imSessionContext.getClient();
        if (client == null) {
            return;
        }
        User onlineUser = client.getUser();
        if (onlineUser != null) {
            initUserTerminal(channelContext, onlineUser.getTerminal(), ONLINE);
            initUserInfo(onlineUser);
        }
    }

    @Override
    public void onAfterUserUnbind(ChannelContext channelContext, String userid) throws Exception {
        if (!isStore()) {
            return;
        }

    }

    /**
     * 初始化群组用户;
     *
     * @param groupId
     * @param channelContext
     */
    public void initGroupUsers(String groupId, ChannelContext channelContext) {
        if (!isStore()) {
            return;
        }
        String userId = channelContext.getUserid();
        if (StringUtils.isEmpty(groupId) || StringUtils.isEmpty(userId)) {
            return;
        }
        String group_user_key = groupId + SUBFIX + USER;
        List<String> users = groupCache.listGetAll(group_user_key);
        if (!users.contains(userId)) {
            groupCache.listPushTail(group_user_key, userId);
        }
        initUserGroups(userId, groupId);

        ImSessionContext imSessionContext = (ImSessionContext) channelContext.getAttribute();
        Client client = imSessionContext.getClient();
        if (client == null) {
            return;
        }
        User onlineUser = client.getUser();
        if (onlineUser == null) {
            return;
        }
        List<Group> groups = onlineUser.getGroups();
        if (groups == null) {
            return;
        }
        for (Group group : groups) {
            if (groupId.equals(group.getGroup_id())) {
                groupCache.put(groupId + SUBFIX + INFO, group);
                break;
            }
        }
    }

    /**
     * 初始化用户拥有哪些群组;
     *
     * @param userid
     * @param group
     */
    public void initUserGroups(String userid, String group) {
        if (!isStore()) {
            return;
        }
        if (StringUtils.isEmpty(group) || StringUtils.isEmpty(userid)) {
            return;
        }
        List<String> groups = userCache.listGetAll(userid + SUBFIX + GROUP);
        if (!groups.contains(group)) {
            userCache.listPushTail(userid + SUBFIX + GROUP, group);
        }
    }

    /**
     * 初始化用户终端协议类型;
     *
     * @param channelContext
     * @param terminal
     * @param status(online、offline)
     */
    @Override
    public void initUserTerminal(ChannelContext channelContext, String terminal, String status) {
        if (!isStore()) {
            return;
        }
        String userId = channelContext.getUserid();
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(terminal)) {
            return;
        }
        userCache.put(userId + SUBFIX + TERMINAL + SUBFIX + terminal, status);
    }

    /**
     * 初始化用户终端协议类型;
     *
     * @param user
     */
    public void initUserInfo(User user) {
        if (!isStore() || user == null) {
            return;
        }
        String userId = user.getId();
        if (StringUtils.isEmpty(userId)) {
            return;
        }
        User userCopy = ImKit.copyUserWithoutFriendsGroups(user);
        userCache.put(userId + SUBFIX + INFO, userCopy);
        List<Group> friends = user.getFriends();
        if (friends != null) {
            userCache.put(userId + SUBFIX + FRIENDS, (Serializable) friends);
        }
    }

    /**
     * 是否开启持久化;
     *
     * @return
     */
    public boolean isStore() {
        return ON.equals(imConfig.getIsStore());
    }
}
